home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
MSC2BC.ARJ
/
BFARHEAP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-22
|
7KB
|
224 lines
/* BFARHEAP.C - Ffar heap example #2.
illustrates Borland C++ 3.0 far heap memory management.
It implements the minimum number of changes to MFARHEAP.C
to compile and run with Borland C++ 3.0. It allocates,
mainpulates, and deallocates two sets of far heap memory
blocks, and shows some of the details about how far heap
management works.
Copyright (c) 1991 Borland International. All rights reserved.
*/
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>
/* Note 1 - Define Borland C++3.0 functions, struct, and variables
for equivalent or near-equivalent Microsoft C6.0a items.
*/
#define _fheapchk farheapcheck
#define _fheapset farheapfillfree
#define _fheapwalk farheapwalk /* but farheapwalk walks only the blocks used */
#define _heapinfo farheapinfo
#define _useflag in_use /* farheapwalk returns different values */
#define _size size /* farheapinfo defines a long unsigned int */
#define _pentry ptr
/* Borland C++ 3.0 _fmalloc does not allocate a block of zero bytes, whereas
Microsoft C6.0a _fmalloc does.
*/
/* Function prototypes and manifest constants */
void heapdump( char fill );
void heap_status( int status );
#define IMAX 10 /* number of heap blocks to allocate */
void main()
{
void _far *p[10];
/* Note 2 - The hblocksize array keeps track of the current
size of each heap block pointer in p. */
int hblocksize[10]; /* Size of each heap block when allocated */
int i, n_alloc;
/* Fill all current heap blocks with known data. */
heap_status( _fheapset( 254 ) );
printf ("Free heap has been initialized.\n");
/* Check heap consistency and dump it before doing anything else. */
heapdump( (char)254 );
/* Check heap status. */
heap_status( _fheapchk() );
printf ("Just before allocating blocks.\n");
/* Now allocate IMAX fixed blocks of memory to affect the far heap,
and fill them with ones. */
for( i = 0; i < IMAX; i++ )
{
/* Note 3 - Calculate and save the size of each heap block. */
hblocksize[i] = (size_t)i*10;
/* Note 4 - Borland C++ will not allow you to allocate a heap block
that is zero bytes in size.
*/
if ( i != 0 )
if( (p[i] = _fmalloc( (size_t)i*10 )) != NULL )
printf( "Allocated %u bytes on far heap at %Fp\n",
hblocksize[i], p[i] );
else
break;
}
n_alloc = i-1; /* Index of last block successfully allocated */
/* Note 5 - The Borland C++ heap manager allocates all
unused conventional DOS memory to the far heap. It
also concatenates adjacent free heap blocks together
to form a single contiguous heap block at the time when
a heap block is freed.
*/
printf ("Just after allocating heap blocks.\n" );
/* Fill all free heap blocks with known data. */
heap_status( _fheapset( 254 ) );
printf ("Free heap has been initialized again.\n" );
/* Fill all allocated heap blocks with different data. */
for( i = 0; i < n_alloc; i++ )
if ( i != 0 )
_fmemset( p[i], 0xFF, hblocksize[i] );
printf ("All allocated heap blocks are now filled with 0xFF.\n" );
/* Check heap consistency again. */
heapdump( (char)254 );
/* Now free up the heap blocks. */
for( i=n_alloc; i >= 0; i-- )
if ( i != 0 )
{
printf( "Deallocating %u bytes from far heap at %Fp\n",
hblocksize[i], p[i] );
_ffree( p[i] );
}
/* Check heap consistency after releasing memory. */
heapdump( (char)254 );
/* Now AGAIN allocate IMAX fixed blocks of memory to affect
the far heap, and fill them with ones. This will see whether
free heap gets concatenated together to satisfy a request.
*/
printf ("Just before allocating blocks second time.\n");
for( i = 0; i < IMAX; i++ )
{
if ( i != 0 )
if( (p[i] = _fmalloc( (size_t)i*10 )) != NULL ) /* farmalloc */
printf( "Allocated %u bytes on far heap at %Fp\n",
hblocksize[i], p[i] );
else
break;
}
n_alloc = i-1; /* Index of last block successfully allocated */
printf ("Just after allocating heap blocks second time.\n" );
/* Fill all free heap blocks with known data. */
heap_status( _fheapset( 254 ) );
printf ("Free heap has been initialized again.\n" );
/* Fill all allocated heap blocks with different data. */
for( i = 0; i < n_alloc; i++ )
if ( i != 0 )
_fmemset( p[i], 0, hblocksize[i] );
printf ("All allocated heap blocks are now filled with 0.\n" );
/* Check heap consistency again. */
heapdump( (char)254 );
/* Now free up the heap blocks. */
for( i=n_alloc; i >= 0; i-- )
if ( i != 0 )
{
printf( "Deallocating %u bytes from far heap at %Fp\n",
hblocksize[i], p[i] );
_ffree( p[i] );
}
/* Final check of heap consistency. */
heapdump( (char)254 );
exit(0);
}
void heapdump( char fill )
/* heapdump walks through all heap entries, checks consistency
of free blocks, and displays information about each heap block.
*/
{
struct _heapinfo hi;
int hstate, i;
char _far *p;
printf( "\n-- Current Heap Blocks ---\nStatus Size Address\n" );
hi.ptr = NULL; /* Initialize to get first heap entry */
while( ( hstate = _fheapwalk( &hi )) == _HEAPOK )
{
/* Note 6 - A zero value for in_use in a farheapinfo
structure designates a heap block as used.
size is an unsigned long integer, but it reports the size of
the heap block including control information and any memory
added to make the size of the entire block an integral number
of paragraphs in size, i.e. ((size % 16) == 0).
*/
printf( "%s %10lu %Fp\n",
hi._useflag ? "USED" : "FREE",
hi._size,
hi._pentry );
}
/* Note 7 - Check that all free heap entries contain the
requested fill character.
*/
hstate = farheapcheckfree(fill);
if ( hstate < 0)
switch(hstate)
{
case _HEAPCORRUPT:
printf("Heap is corrupted.\n");
break;
case _BADVALUE:
printf("There is a changed value in heap free space.\n");
break;
default:
printf("There is an unknown heap error.\n");
break;
}
else
printf ("Heap status is OK.\n");
}
void heap_status( int heapstate )
/* heap_status decodes the status returned by far heap
management functions _fheapwalk, _fheapset, or _fheapchk,
and displays appropriate text.
*/
{
/* Note 8 - All of the manifest constants used here refer
to heap error values that are common between Borland C++
and Microsoft C6.0a.
*/
switch( heapstate )
{
case _HEAPOK:
printf( "Heap status is OK.\n" );
break;
case _HEAPEMPTY:
printf( "Heap status is empty.\n" );
break;
case _HEAPEND:
printf( "Heap status is at end of heap.\n" );
break;
default:
printf( "Heap status is corrupted.\n" );
break;
}
}